<?php if(!defined('CALL')) exit('No direct script access allowed');

include_once('lib/mysql.class.php');
include_once('lib/utils.class.php');
include_once('lib/logger.class.php');
include_once('cfg/cfg.php');

class mMessages
{
	public static $fields = 
		"SELECT
			e.id as event_id, e.dt, e.dt_beg, c.name as city, u.city_id, 
			e.part_0, e.part_1, e.part_2, e.part_3, e.access,
			u.id as user_id, u.username, u.face, e.note, u.note as user_note";
	
	public function __construct()
	{
		self::init();
	}

	public static function init()
	{
		if(is_null(self::$db))
		{
			global $dburl, $def_encoding;
			MySQL::$url = $dburl;
			MySQL::$encoding = $def_encoding;
			self::$db = MySQL::getInstance();
		}
	}

	public static function insert($sender_id, $user_id, $categ, $note)
	{
		self::init();
		
		$sender_status = ($sender_id == 0) ? 'DEL' : 'NEW';
		
		$sql =
			"INSERT INTO messages(user_id, sender_id, categ, note, status_s) ".
			"VALUES(%s, %s, %s, %s, %s)";

		$note = is_null($note) ? '' : $note;
		$params = array(
			self::$db->escape($user_id),
			self::$db->escape($sender_id),
			self::$db->escape($categ),
			self::$db->escape($note),
			self::$db->escape($sender_status)
			);
		
		$sql = vsprintf($sql, $params);
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);
			
		self::$db->query($sql);
		$id = self::$db->insert_id();
		return $id;
	}
	
	public static function delete($actor_id, $msg_id)
	{
		self::init();
		
		$sql = "SELECT user_id FROM messages WHERE id = $msg_id";
		$res = self::$db->query($sql);
		$row = self::$db->fetch_row($res);
		$user_id = $row[0];
		
		// В этом сообщении актор кто: получатель или отправитель?
		$status_fld = ($user_id == $actor_id) ? 'status_u' : 'status_s';
		
		
		/// TODO удалять сначала записи из подчиненных таблиц
		$sql = "UPDATE messages SET $status_fld = 'DEL' WHERE id = $msg_id";
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);
		$res = self::$db->query($sql);
		
		return (bool)(self::$db->affected_rows() > 0);
		// return true;
	}

	public static function set_status($msg_id_list, $status, $for_sender = FALSE)
	{
		$ids = '0';
		if(count($msg_id_list) > 0)
			$ids .= ','.implode(',', $msg_id_list);
		self::init();
		$fld_name = ($for_sender) ? 'status_s' : 'status_u';
		$sql = "UPDATE messages SET $fld_name = '".$status."' WHERE id in ($ids)";
		$res = self::$db->query($sql);
	}
	
	public static function select_private($actor_id, $user_id, $num = 100)
	{
		self::init();
		
		$sql =
			"SELECT m.id, m.user_id, m.sender_id, m.dt, m.categ, m.note ".
			  "FROM messages m ".
			 "WHERE ((m.sender_id = %s AND m.user_id = %s AND m.status_s != 'DEL') OR (m.sender_id = %s AND m.user_id = %s) AND m.status_u != 'DEL') ".
			   "AND m.categ = 'PRIVATE' ".
			 "ORDER BY m.id DESC ".
			 "LIMIT 100";

		$params = array(
			self::$db->escape($actor_id),
			self::$db->escape($user_id),
			self::$db->escape($user_id),
			self::$db->escape($actor_id)
			);
		
		$sql = vsprintf($sql, $params);

		
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);
			
		$res = self::$db->query($sql);
		
		$messages = array();
		while($row = self::$db->fetch_assoc($res))
		{
			$row['note'] = Utils::safe_encode($row['note']);
			$messages[$row['categ']][$row['id']] = $row;
		}
		self::$db->free_result($res);

		// Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, print_r($messages, TRUE));
		
		return $messages;
	}
	
	public static function select_system($actor_id)
	{
		self::init();
		
		$cond_categ = "";
		// $cond_categ = "AND m.categ != 'PRIVATE' ";
		switch($_SESSION['categ'])
		{
			case 'events':
				$cond_categ = " AND m.categ in ('COMMENT', 'EVENT', 'SHARE', 'SPAM') ";
				break;
			
			case 'private':
				$cond_categ = " AND m.categ in ('PRIVATE') ";
				break;
			
			case 'users':
				$cond_categ = " AND m.categ in ('FRIEND', 'WATCH') ";
				break;
			
			case 'sys':
				$cond_categ = " AND m.categ in ('NEWS', 'ALERT', 'SYS') ";
				break;
		}
		 
		
		$sql =
			"SELECT m.id, m.user_id, m.sender_id, m.dt, m.categ, m.status_u, m.note ".
			  "FROM messages m ".
			 "WHERE m.status_u != 'DEL' AND m.user_id = $actor_id ".$cond_categ.
			 "ORDER BY m.id DESC ".
			 "LIMIT 100";
		
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);
			
		$res = self::$db->query($sql);
		
		$id_list = array();
		$messages = array();
		while($row = self::$db->fetch_assoc($res))
		{
			if($row['categ'] == 'PRIVATE')
			{
				$row['note'] = Utils::safe_encode($row['note']);
			}
			
			// Собираем ID всех новых сообщений для установки их в старые
			if($row['status_u'] == 'NEW') $id_list[] = $row['id'];
			
			$messages[$row['categ']][$row['id']] = $row;
		}
		self::$db->free_result($res);
		
		self::set_status($id_list, 'OLD');
		
		if(isset($messages['PRIVATE']) && count($messages['PRIVATE']) > 0)
			self::add_details($messages['PRIVATE']);
		return $messages;
	}
	
	private static function add_details(&$messages)
	{
		if(is_null($messages) || count($messages) == 0) return;
		
		$arr = array();
		foreach($messages as $m)
			$arr[] = $m['sender_id'];
		
		$list = implode(',', $arr);
		$users = mUser::get_props($list, TRUE);
		
		foreach($messages as $id=>$m)
		{
			$uid = $m['sender_id'];
			if($uid == 0) continue;
			$note = $m['note'];
			$url = ROOT_URL.'/'.$uid.'/messages/';
			$messages[$id]['note'] = 
					'<a href="'.$url.'" class="its_user" name="user-'.$uid.'">'.
					$users[$uid]['username'].'</a> написал: '.
					$note.
					' [<a href="'.$url.'">переписка</a>]';
		}
	}
	
	public static function get_news_num($actor_id)
	{
		if(is_null($actor_id) || ($actor_id == 0)) return 0;
		
		self::init();
		$sql =
			"SELECT count(m.id) ".
			  "FROM messages m ".
			 "WHERE m.status_u = 'NEW' ".
			//   "AND m.categ != 'PRIVATE' ".
			   "AND m.user_id = $actor_id ".
			 "ORDER BY m.id DESC";
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);

		$res = self::$db->query($sql);
		
		$id_list = array();
		$messages = array();
		$row = self::$db->fetch_row($res);
		$num = $row[0];
		self::$db->free_result($res);
		return $num;
	}
	
	public static function get($message_id)
	{
		self::init();
		
		$sql =
			"SELECT m.id, m.user_id, m.sender_id, m.dt, m.categ, m.note ".
			  "FROM messages m WHERE m.id = $message_id";
		
		if(LOG_SQL) Logger::Write(__FILE__." ".__FUNCTION__." line: ".__LINE__, $sql);
			
		$res = self::$db->query($sql);
		
		$row = self::$db->fetch_assoc($res);
		$row['note'] = Utils::safe_encode($row['note']);
		self::$db->free_result($res);

		return $row;
	}
	
	
	
	public static function for_event($event_id, $actor, $categ = 'ins')
	{
		$e = mEvents::get($event_id);
		if($e == null) return;
		
		$e_ref = '<a href="'.ROOT_URL.'/'.$event_id.'/event/share">событие</a>';
		$u = '<a href="'.ROOT_URL.'/'.$actor->id.'/plans">'.$actor->props['username'].'</a>';
		$msg = $u.' запланировал новое '.$e_ref;
		switch($categ)
		{
			case 'upd':
				$msg = $u.' изменил '.$e_ref;
				break;
			case 'del':
				$msg = $u.' отменил событие: '.$e['note'];
				break;
		}
		
		// по умолчанию событие доступно только себе,
		// и уведомлять никого не надо
		$users = array();
		switch($e['access'])
		{
			case 'F':
				$users = array_intersect($actor->links['WS'], $actor->links['FM']);
				break;
			
			case 'A':
				$users = $actor->links['WS'];
				break;
		}
		
		// рассылка в соответствии с правами доступа
		if(count($users) > 0)
			foreach($users as $user_id)
				self::insert(0, $user_id, 'EVENT', $msg);
	}
	
	public static function forLink($user_id, $actor, $link_type, $act_type = 'ins')
	{
		$msg = '<a href="'.ROOT_URL.'/'.$actor->id.'/users">'.$actor->props['username'].'</a>';
		// $msg = $actor->props['username'];
		$msg .= ($act_type == 'ins') ? ' начал' : ' перестал';
		$msg .= ($link_type == 'F') ? ' доверять Вам' : ' следить за Вами';
		$cat .= ($link_type == 'F') ? 'FRIEND' : 'WATCH';
		mMessages::insert($actor->id, $user_id, $cat, $msg);
	}
	
	private static $db = null;

}